<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>jPOS' miniSpace</title>

<style type="text/css">
 body {
  font-family: trebuchet ms, verdana, tahoma, arial;
  font-style: normal;
  color: #000000;
  background-color: #FFFFFF;
  margin-left: 10%; 
  margin-right: 20%; 
 }
 h1 { font-size: x-large; }
 h2 { font-size: large; }
 h3 { font-size: medium; }
 li { padding-bottom: 1em; }
 li:first-line { font-weight: bold; }

 hr {
  border-color: #000;
  border-top-style: solid;
  height: 1px;
 }

 pre {
  width: 100%;
  font-size: 80%;
  font-family: "Courier New", Courier, mono;
  background-color: #e6e2ff;
  border-top-style: groove;
  border-right-style: groove;
  border-left-style: groove;
  border-bottom-style: groove;
  border-color: #ddd;
 }
 .imageright {
  position: 0 0 0 0;
  float: right;
  margin: 0;
  padding: 0% 0% 0% 3%;
 }
 .imageleft {
  float: left;
  margin: 0;
  padding: 0% 0% 0% 3%;
 }
 .rightquote {
  float: right;
  width: 150px;
  margin: 0px 0px 0px 10px;
  padding: 0px 20px 10px 20px;
  font-family: georgia;
  font-size: 80%;
  font-style: italic;
  line-height: 1.8em;
  color: #555;
  background: #eee;
  border-color: #ddd;
  border-top-style: groove;
  border-right-style: groove;
  border-left-style: groove;
  border-bottom-style: groove;
 }
 #content{
  float: left;
  width: 75%;
  margin: 0;
  padding: 0 3% 0 0;
  margin-left: 10%; 
  margin-right: 20%; 
 }
</style>
</head>

<body>
 <a href="http://jpos.org"><img class="imageright" width="8%"
    src="http://jpos.org/images/jpos_l.jpg" border="0" alt="jPOS"></img></a>

 <h1><i>miniSpace</i> - 5 minutes tutorial</h1>
 <hr/>
 <h2>A minimalist coordination mechanism</h2>

 <p align='justify'>
  <b><i>miniSpace</i></b> is a general-purpose coordination mechanism inspired after
  the <a href="http://en.wikipedia.org/wiki/Linda_%28coordination_language%29">Linda</a> 
  Coordination Language and 
  <a href="http://en.wikipedia.org/wiki/JavaSpaces">JavaSpaces</a>.
  It is <b>by no means</b> an attempt to implement any of those, we just implemented 
  the minimum set of concepts we needed in our own projects.
 </p>

 <p align='justify'>
   You can think about a Space instance as being like a Map where its
   entries are lists of objects and its operations are fully synchronized.
 </p>

 <p align='justify'>
  There are three basic operations:
  <ul>
   <li>
    void out (Object key, Object value)<br/>
    Put an object into the space. If an object under the
    given key already exists, the object is queued at the end of a list.
   </li>
   <li>
    Object rd (Object key)<br/>
    Reads an object from the space. Block until one is present under the given key.
   </li>
   <li>
    Object in (Object key)<br/>
    Take the object off the queue. Block until the object under
    the given key is present.
   </li>
  </ul>
 </p>
 <p align='justify'>
  In addition to those three basic operations it also has a few handy methods:
  <ul>
   <li>
    void out (Object key, Object value, long timeout)<br/>
    Place an object into the space using an expiration timeout.
    The entry is automatically removed upon expiration.
   </li>
   <li>
    Object rd (Object key, long timeout)<br/>
    Wait a maximum of <code>timeout</code> milliseconds
    for a given entry; otherwise, return null.
   </li>
   <li>
    Object in (Object key, long timeout)<br/>
    Wait a maximum of <code>timeout</code> milliseconds for
    a given entry; otherwise, return null
   </li>
   <li>
    Object rdp (Object key)<br/>
    Read an entry if it exists. (p for 'probe')
   </li>
   <li>
    Object inp (Object key)<br/>
    Take an entry if it exists. (p for 'probe')
   </li>
  </ul>
 </p>

 <h2>Hello miniSpace</h2>
 <hr/>
 <p align='justify'>
  Let's have a look at a simple example, we will put two Strings in the Space
  under the key name "Test" (we call them 'queues') by using the
  <b>out</b> operation. The first string equals to
  "Hello ", and the second one equals to "World". 
 </p>
 <p align='justify'>
  Then we will take and print one entry at a time off the "Test" queue by
  using the <b>in</b> operation.
 </p>
 <p align='justify'>
  Finally we will read (rd) that queue using the <b>rdp</b> (read-probe)
  operation. It should be null (because there were just two entries under
  the name 'Test' and we have already taken them off the Space).
 </p>
 <pre>

  import org.jpos.space.*;

  Space sp = SpaceFactory.getSpace(); // get a reference to the default Space
  sp.out ("Test", "Hello ");          // put "Hello " in the "Test" queue
  sp.out ("Test", "World");           // put "World" in the "Test" queue
  System.out.print (sp.in ("Test"));  // should return the first entry
  System.out.print (sp.in ("Test"));  // should return the second entry
  if (sp.rdp ("Test") == null)        // should be null
    System.out.println (".");

  --- output ---
  Hello World.

 </pre>
 <p align='justify'>
  We encourage you to play with the previous code and we suggest you
  perform some of the following variations in order to understand how 
  it works:
  <ul>
   <li>Use a timeout at read time<br/>
    Change the final sp.rdp ("Test") and use sp.rd ("Test", 5000) instead. 
    You will see how it takes 5 seconds to print the final dot. You can try
    sp.inp instead of sp.in too.
   </li>
   <li>Use a timeout at write time<br/>
   Try to out an entry with a timeout, e.g.: sp.out("Test", "City", 1000L);
   Then play with some Thread.sleep(xxx) here and there and sp.rd ("Test")
   in order to verify that the entry is available for just one second.
   </li>
   <li>Play with different keys<br/>
    Write (out), take (in) and read (rd) entries using different keys
    other than "Test". Try with objects other than Strings.
   </li>
  </ul>
 </p>
 <h2>Some use cases</h2>
 <ul>
  <li>A simple ThreadPool<br/>
  You can implement a ThreadPool with a few lines of code, the workers
  would be a set of threads running a loop like this:
  <pre>

    public void run() {
       Space sp = SpaceFactory.getSpace();
       for (;;) {
          Runnable r = (Runnable) sp.in ("MyPool");
          try {
            r.run();
          } catch (Exception e) {
            e.printStackTrace();
          }
       }
    }

  </pre>
  When you need to run something controlled by the thread pool,
  you would just queue a Runnable object into the "MyPool" queue,
  e.g.:
  <pre>

   Space sp = SpaceFactory.getSpace();
   sp.out ("MyPool", MyRunnable);

  </pre>
  </li>
  <li>License control<br/>
  Imagine you have a system where you want to limit throughput to
  10 outstanding transactions at any given point in time. At startup you
  could <b>out</b> 10 "tickets" into the Space under a well known
  name, then you could use code like this in order to control 
  throughput:
  <pre>

   Object ticket = null;
   try {
      ticket = sp.in ("TransactionTickets");
      ...
      ...
      ...
   } finally {
      sp.out ("TransactionTickets", ticket); // back to the ticket pool
   }
  </pre>


  </li>
  <li>Simple cache<br/>
  You read some objects from a database that makes sense to cache for
  a few minutes, you just out them under a given name specifying a
  timeout, e.g.:
  <pre>

    Space sp = SpaceFactory.getSpace();
    for (;;) {
      BigDecimal exchangeRate = getExchangeRateFromDB(...);
      sp.out ("ExchangeRate", exchangeRate, 120000L);
      Thread.sleep (110000L);   // get a new one before it expires ...
    }
    
  </pre>

  Then any client code can just block waiting for a valid and up-to-date
  ExchangeRate object to be available in the space, e.g.:
  <pre>

     BigDecimal exchangeRate = (BigDecimal) sp.in ("ExchangeRate");

  </pre>

  or better yet, wait for a reasonable time for a valid exchange rate
  to be available in the Space (think database down) and throw an
  exception if it doesn't get available.

  <pre>

     BigDecimal exchangeRate = (BigDecimal) sp.in ("ExchangeRate", 10000L);
     if (exchangeRate == null)
        throw new XXXException ("Exchange rate is not available");

  </pre>
  </li>
  <li>Reading devices - a jPOSsy real world example<br/>
  We want to read a credit card at a POS terminal in order to initiate a transaction.
  We want that read to remain valid just for a short period of time, if
  the operator doesn't complete the transaction, we want that read to be
  discarded. We can do that without miniSpace in many different ways, but
  with miniSpace it's a no-brainer. There's a thread reading the cards and
  placing them in the space:
  <pre>

    for (;;) {
        CardData cd = readCardData(...);
        SpaceUtil.wipe (sp, "CARDDATA"); // clear buffer
        sp.out ("CARDDATA", cd, 60000L); // buffered for just 1 minute
    }

  </pre>

  Then at the UI level we can asynchroneously ask for the transaction type,
  amount, etc. At any point where we need the card data, we would just call:

  <pre>
     
     // gives the operator up to two minutes to swipe the card
     CardData cd = (CardData) sp.in ("CARDDATA", 120000L); 
     ...
     ...

  </pre>
  </li>
 </ul>

 <h2>The persistent Space</h2>
 <p align='justify'>
  When you call <code>SpaceFactory.getSpace()</code> you are actually getting
  an instance of TSpace. That Space gets registered under the name 
  <b>tspace:default</b>. So calling <code>SpaceFactory.getSpace()</code> is
  exactly the same as calling
  <code>SpaceFactory.getSpace("tspace:default")</code>.
 </p>
 <p align='justify'>
  You can create as many Spaces as you want, and you can make them anonymous
  if you go directly to the Space constructur instead of using the SpaceFactory
  helper class.
 </p>
 <p align='justify'>
  There's a very useful space implementation called <b>JDBMSpace</b>. It is a
  persistent space implementation that uses a <a href="http://jdbm.sf.net" target="_new">JDBM</a> 
  database as its back end. The result is that everything you write there will
  remain valid across JVM runs.
 </p>
 <p align='justify'>
  You can use a JDBMSpace by calling:
  <pre>

  Space sp = SpaceFactory ("jdbm:mypersistentspace");

  </pre>

  You can also specify an optional path for your JDBM database:

  <pre>

  Space sp = SpaceFactory ("jdbm:mypersistentspace:/tmp/persistentspace");

  </pre>
 </p>
 <hr/>
 <h2>What's next ?</h2>
 <p align='justify'>
  You can get additional information in the 
   <a href="http://code.google.com/p/minispace/">project page</a> at Google
   Code.
 </p>
</body>
</html>

